package com.sooncode.project.focusservice.model;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.sooncode.project.core.annotations.Lookup;
import com.sooncode.project.core.annotations.LookupModel;
import com.sooncode.project.core.finder.Finder;
import com.sooncode.project.core.generic.BasicModifyEvent;
import com.sooncode.project.core.model.DomainException;
import com.sooncode.project.focusservice._.base.BaseDomainModel;
import com.sooncode.project.focusservice._.base.Utils;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

@Data
@LookupModel
public class Test extends BaseDomainModel<Test> {
    private String orgId;
    @Lookup(fromModel = Organization.class,localField = "orgId",fromField = "name")
    private String orgName;
    private String memberId;
    @Lookup(fromModel = Member.class,localField = "memberId",fromField = "member_no")
    private String member_no;
    private String check_type;
    private String teacher;
    @Lookup(fromModel = Member.class,localField = "memberId",fromField = "name")
    private String name;
    @Lookup(fromModel = Member.class,localField = "memberId",fromField = "sex")
    private String sex;
    @Lookup(fromModel = Member.class,localField = "memberId",fromField = "birth")
    private String birth;
    @Lookup(fromModel = Member.class,localField = "memberId",fromField = "age")
    private String age;
    @Lookup(fromModel = Member.class,localField = "memberId",fromField = "showAge")
    private String showAge;
    private String pid;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date testDate;
    private Double totalScore;
    private Double averageScore;
    private boolean downloadCourse;
    private List<Date> downloadDate;
    private List<TestData> data;
    private Map<String,Double> typeTotal;
    private Map<String,Double> typeAverage;
    private boolean last;
    private int testCount;
    @Lookup(fromModel = Member.class,localField = "memberId",fromField = "classId")
    private String classId;
    @Lookup(fromModel = Member.class,localField = "memberId",fromField = "className")
    private String className;
    @Lookup(fromModel = Member.class,localField = "memberId",fromField = "classYear")
    private String classYear;
    @Override
    public void add(Map map){
        if(StringUtils.isEmpty(map.get("memberId").toString())){
            throw new DomainException("memberId不能为空");
        }
        Member member=new Finder<>(Member.class).byId(map.get("memberId").toString());
        List<TestData> data=List.class.cast(map.get("data"));
        //计算等级
        List<TestLevel> levelList=new Finder<>(TestLevel.class)
                .byField("age",Test.getTestAge(member.getAge())).list();
        Map<String,Integer> levelMap=new HashMap();
        levelMap.put("未测试",0);
        levelMap.put("极弱",1);
        levelMap.put("较弱",2);
        levelMap.put("不足",3);
        levelMap.put("中等",4);
        levelMap.put("优秀",5);
        int count=0;
        Double total=0.0;
        Map<String,Double> typeMap=new HashMap<>();
        Map<String, Double> typeCount=new HashMap<>();
        for(TestData d:data){
            String levelName="未测试";
            double score=d.getItem_score()<0?0:d.getItem_score();
            TestLevel level=levelList.stream().filter(f->{
                return f.getItemCode().equals(d.getItem_no())
                        &&f.getMinScore()<=score
                        &&f.getMaxScore()>=score;
            }).findFirst().orElse(null);
            if(d.getItem_score()>=0){
                if(level==null)
                    throw new DomainException("没有找到对应的配置[01]");
                else levelName=level.getLevel();
            }
            if(!typeMap.containsKey(level.getItemType())) {
                typeMap.put(level.getItemType(), 0.0);
                typeCount.put(level.getItemType(), 0.0);
            }
            typeCount.put(level.getItemType(), typeCount.get(level.getItemType()) + 1);
            d.setItemName(level.getItemName());
            d.setTestType(level.getItemType());
            d.setLevelScore(levelMap.get(levelName));
            typeMap.put(level.getItemType(), typeMap.get(level.getItemType()) + d.getLevelScore());
            d.setLevel(levelName);
            d.setMinScore(level.getMinScore());
            d.setMaxScore(level.getMaxScore());
            count++;
            total+=levelMap.get(level.getLevel());
        }
        map.put("typeTotal",typeMap);
        for(Map.Entry<String,Double> e:typeMap.entrySet()){
            double v=typeCount.get(e.getKey())==0?0:typeMap.get(e.getKey())/typeCount.get(e.getKey());
            v= Utils.doubleFormat2(v);
            typeCount.put(e.getKey(),v);
        }
        map.put("typeAverage",typeCount);
        map.put("totalScore",total);
        map.put("averageScore",count==0?0:Utils.doubleFormat2(total/count));
        map.put("data",data);
        map.put("testDate",new Date());
        map.put("last",true);
        map.put("age",member.getAge());
        map.put("showAge",member.getShowAge());
        List<Test> testList=new Finder<>(Test.class)
                .byField("memberId",map.get("memberId"))
                .and("last",true).list();
        for(Test test:testList){
            test.setLast(false);
            test.update();
        }
        long testCount=new Finder<>(Test.class)
                .byField("memberId",member.getId()).count();
        map.put("testCount",testCount);
        super.add(map);
    }
    public void update(){
        causes(BasicModifyEvent.class,this);
    }

    public static String getTestAge(String theAge){
        int age=Integer.parseInt(theAge);
        if(age<2)age=2;
        if(age>12)age=12;
        return age+"";
    }

    public void doDownloadCourse() {
        setDownloadCourse(true);
        if(downloadDate==null)downloadDate=new ArrayList<>();
        downloadDate.add(new Date());
        update();
    }
}
